类模板可偏特化。可以为特定的情况提供特殊的实现，但有些模板参数仍需要由用户定义。例如，可以为指针定义Stack<>类的特殊实现:

\hspace*{\fill} \\ %插入空行
\noindent
\textit{basics/stackpartspec.hpp}
\begin{lstlisting}[style=styleCXX]
#include "stack1.hpp"

// partial specialization of class Stack<> for pointers:
template<typename T>
class Stack<T*> {
private:
	std::vector<T*> elems; // elements
	
public:
	void push(T*); // push element
	T* pop(); // pop element
	T* top() const; // return top element
	bool empty() const { // return whether the stack is empty
		return elems.empty();
	}
};

template<typename T>
void Stack<T*>::push (T* elem)
{
	elems.push_back(elem); // append copy of passed elem
}

template<typename T>
T* Stack<T*>::pop ()
{
	assert(!elems.empty());
	T* p = elems.back();
	elems.pop_back(); // remove last element
	return p; // and return it (unlike in the general case)
}

template<typename T>
T* Stack<T*>::top () const
{
	assert(!elems.empty());
	return elems.back(); // return copy of last element
}
\end{lstlisting}

\begin{lstlisting}[style=styleCXX]
template<typename T>
class Stack<T*> {
};
\end{lstlisting}

先定义了一个类模板，仍然参数化了T，但特化了指针(Stack<T*>)。

特化可能提供(略微)不同的接口。例如，这里的pop()返回存储的指针，当用new创建值时，用户就可以使用delete删除:

\begin{lstlisting}[style=styleCXX]
Stack<int*> ptrStack; // stack of pointers (special implementation)

ptrStack.push(new int{42});
std::cout << *ptrStack.top() << '\n';
delete ptrStack.pop();
\end{lstlisting}

\hspace*{\fill} \\ %插入空行
\noindent
\textbf{多个参数的偏特化}

类模板也可以特化多个模板参数之间的关系。例如，对于以下类模板:

\begin{lstlisting}[style=styleCXX]
template<typename T1, typename T2>
class MyClass {
	...
};
\end{lstlisting}

以下几种可能的偏特化:

\begin{lstlisting}[style=styleCXX]
// partial specialization: both template parameters have same type
template<typename T>
class MyClass<T,T> {
	...
};

// partial specialization: second type is int
template<typename T>
class MyClass<T,int> {
	...
};

// partial specialization: both template parameters are pointer types
template<typename T1, typename T2>
class MyClass<T1*,T2*> {
	...
};
\end{lstlisting}

下面的例子显示了哪个声明使用了哪个模板:

\begin{lstlisting}[style=styleCXX]
MyClass<int,float> mif; // uses MyClass<T1,T2>
MyClass<float,float> mff; // uses MyClass<T,T>
MyClass<float,int> mfi; // uses MyClass<T,int>
MyClass<int*,float*> mp; // uses MyClass<T1*,T2*>
\end{lstlisting}

若多个偏特化都匹配调用，则声明有歧义:

\begin{lstlisting}[style=styleCXX]
MyClass<int,int> m; // ERROR: matches MyClass<T,T>
					// and MyClass<T,int>
MyClass<int*,int*> m; // ERROR: matches MyClass<T,T>
					  // and MyClass<T1*,T2*>
\end{lstlisting}

要解决歧义，可以为相同类型的指针提供偏特化实现:

\begin{lstlisting}[style=styleCXX]
template<typename T>
class MyClass<T*,T*> {
	...
};
\end{lstlisting}

有关偏特化的详细信息，请参见第16.4节。






